#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <netinet/tcp.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <fcntl.h>
#include <errno.h>    // POSIX 标准头文件
#include <sys/errno.h> // 部分系统需要此头文件



// #define MAX_EVENTS 1024
// #define PORT 7073
// #define BUFFER_SIZE 1024

// // 设置文件描述符为非阻塞模式
void set_nonblocking(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}

// int main() {
//     // int listen_fd, conn_fd, epoll_fd;
//     // struct sockaddr_in server_addr, client_addr;
//     // socklen_t client_len = sizeof(client_addr);
//     // struct epoll_event ev, events[MAX_EVENTS];
//     // char buffer[BUFFER_SIZE];

//     // // 1. 创建监听套接字
//     // listen_fd = socket(AF_INET, SOCK_STREAM, 0);
//     // if (listen_fd == -1) {
//     //     perror("socket");
//     //     exit(EXIT_FAILURE);
//     // }
//     //  set_nonblocking(listen_fd);
//     // // 2. 绑定地址和端口
//     // memset(&server_addr, 0, sizeof(server_addr));
//     // server_addr.sin_family = AF_INET;
//     // server_addr.sin_addr.s_addr = INADDR_ANY;
//     // server_addr.sin_port = htons(PORT);
//     // if (bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
//     //     perror("bind");
//     //     close(listen_fd);
//     //     exit(EXIT_FAILURE);
//     // }

//     // // 3. 监听连接
//     // if (listen(listen_fd, SOMAXCONN) == -1) {
//     //     perror("listen");
//     //     close(listen_fd);
//     //     exit(EXIT_FAILURE);
//     // }

//     // // 4. 创建 epoll 实例
//     // epoll_fd = epoll_create1(0);
//     // if (epoll_fd == -1) {
//     //     perror("epoll_create1");
//     //     close(listen_fd);
//     //     exit(EXIT_FAILURE);
//     // }

//     // // 5. 将监听套接字加入 epoll
//     // ev.events = EPOLLIN | EPOLLET;  // 边缘触发模式
//     // ev.data.fd = listen_fd;
//     // if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) {
//     //     perror("epoll_ctl: listen_fd");
//     //     close(epoll_fd);
//     //     close(listen_fd);
//     //     exit(EXIT_FAILURE);
//     // }

//     // printf("Server running on port %d...\n", PORT);

//     // while (1) {
//     //     // 6. 等待事件就绪
//     //     int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
//     //     if (nfds == -1) {
//     //         perror("epoll_wait");
//     //         break;
//     //     }

//     //     for (int i = 0; i < nfds; i++) {
//     //         // 6.1 处理新连接
//     //         if (events[i].data.fd == listen_fd) {
//     //             while (1) {  // ET 模式需循环 accept 直到无新连接
//     //                 conn_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &client_len);
//     //                  printf("conn_fd:%d\n",conn_fd);
//     //                 if (conn_fd == -1) {
//     //                     if (errno == EAGAIN || errno == EWOULDBLOCK) break; // 无新连接
//     //                     perror("accept");
//     //                     break;
//     //                 }

//     //                 printf("New connection from %s\n", inet_ntoa(client_addr.sin_addr));
//     //                 set_nonblocking(conn_fd);  // 设置非阻塞

//     //                 // 将新连接加入 epoll 监听
//     //                 ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP; // 监听读事件+连接关闭
//     //                 ev.data.fd = conn_fd;
//     //                 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &ev) == -1) {
//     //                     perror("epoll_ctl: conn_fd");
//     //                     close(conn_fd);
//     //                 }
//     //             }
//     //         } 
//     //         // 6.2 处理数据可读
//     //         else if (events[i].events & EPOLLIN) {
//     //             int fd = events[i].data.fd;
//     //             // ET 模式需循环读取直到无数据
//     //             while (1) {
//     //                 ssize_t count = read(fd, buffer, BUFFER_SIZE - 1);
//     //                 if (count == -1) {
//     //                     if (errno == EAGAIN) break; // 数据读完
//     //                     perror("read");
//     //                     close(fd);
//     //                     break;
//     //                 } else if (count == 0) { // 客户端关闭连接
//     //                     printf("Client disconnected\n");
//     //                     close(fd);
//     //                     epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); // 移除监听
//     //                     break;
//     //                 }
//     //                 buffer[count] = '\0';
//     //                 printf("Received: %s", buffer);
//     //                 // 回显数据（实际应用中可能需异步写）
//     //                 write(fd, buffer, count);
//     //             }
//     //         }
//     //         // 6.3 处理连接关闭 (EPOLLRDHUP 是 Linux 2.6.17+ 特性)
//     //         else if (events[i].events & (EPOLLRDHUP | EPOLLHUP)) {
//     //             printf("Connection closed by client\n");
//     //             close(events[i].data.fd);
//     //             epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
//     //         }
//     //     }
//     // }

//     // // 7. 清理资源
//     // close(epoll_fd);
//     // close(listen_fd);
//     return 0;
// }

// int main() {
//     int sock_fd = socket(AF_INET, SOCK_STREAM, 0); // 创建 TCP Socket
//     if (sock_fd < 0) {
//         perror("socket() failed");
//         return 1;
//     }

//     // 1️⃣ 获取发送/接收缓冲区大小 (SO_SNDBUF/SO_RCVBUF)
//     int snd_buf, rcv_buf;
//     socklen_t len = sizeof(snd_buf);
//     if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, &snd_buf, &len) == 0) {
//         printf("发送缓冲区大小: %d bytes\n", snd_buf);
//     }
//     getsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf, &len);
//     printf("接收缓冲区大小: %d bytes\n", rcv_buf);

//     // 2️⃣ 获取 Socket 类型 (SO_TYPE)
//     int sock_type;
//     getsockopt(sock_fd, SOL_SOCKET, SO_TYPE, &sock_type, &len);
//     const char* type_str = (sock_type == SOCK_STREAM) ? "TCP" : "UDP";
//     printf("Socket 类型: %s\n", type_str);

//     // 3️⃣ 获取发送超时值 (SO_SNDTIMEO)
//     struct timeval snd_timeout;
//     len = sizeof(snd_timeout);
//     if (getsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, &snd_timeout, &len) == 0) {
//         printf("发送超时: %ld 秒 %ld 微秒\n", snd_timeout.tv_sec, snd_timeout.tv_usec);
//     } else {
//         printf("发送超时未设置（默认无限等待）\n");
//     }

//     // 4️⃣ 获取 TTL 值 (IP_TTL for IPv4)
//     int ttl;
//     len = sizeof(ttl);
//     if (getsockopt(sock_fd, IPPROTO_IP, IP_TTL, &ttl, &len) == 0) {
//         printf("TTL 值: %d\n", ttl); // 默认通常为 64 或 128
//     }

//     // 5️⃣ 获取 TCP 最大分段大小 (TCP_MAXSEG)
//     if (sock_type == SOCK_STREAM) { // 仅 TCP 有效
//         int mss;
//         len = sizeof(mss);
//         if (getsockopt(sock_fd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len) == 0) {
//             printf("TCP 最大分段大小 (MSS): %d bytes\n", mss); // 通常为 536~1460
//         }
//     }

//     close(sock_fd);
//     return 0;
// }
int main() {
    int sockfd;
    struct ifreq ifr;
    struct ifconf ifc;
    char buf[256]; // 缓冲区存储接口信息
    char ip_addr[INET_ADDRSTRLEN]; // 存储点分十进制IP
    
    // 创建原始套接字
    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("socket() failed");
        exit(EXIT_FAILURE);
    }

    // 1️⃣ 获取所有网络接口列表
    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
        perror("ioctl(SIOCGIFCONF) failed");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 2️⃣ 遍历每个网络接口
    struct ifreq *it = ifc.ifc_req;
    const struct ifreq *end = it + (ifc.ifc_len / sizeof(struct ifreq));
    printf("本地网络接口信息：\n");
    printf("--------------------------------\n");

    for (; it != end; ++it) {
        char mac_addr[256] = {0}; // 存储MAC地址字符串
        
        // 跳过回环接口 (lo)
        if (strcmp(it->ifr_name, "lo") == 0) continue;

        // 3️⃣ 获取IP地址 (IPv4)
        if (ioctl(sockfd, SIOCGIFADDR, it) != -1) {
            struct sockaddr_in *ip_addr_in = (struct sockaddr_in *)&it->ifr_addr;
            inet_ntop(AF_INET, &ip_addr_in->sin_addr, ip_addr, INET_ADDRSTRLEN);
        } else {
            strcpy(ip_addr, "N/A");
        }

        // 4️⃣ 获取MAC地址
        if (ioctl(sockfd, SIOCGIFHWADDR, it) != -1) {
            unsigned char *mac = (unsigned char *)it->ifr_hwaddr.sa_data;
            snprintf(mac_addr, sizeof(mac_addr), 
                    "%02X:%02X:%02X:%02X:%02X:%02X",
                    mac, mac, mac, mac, mac, mac);
        } else {
            strcpy(mac_addr, "N/A");
        }

        // 5️⃣ 打印接口信息
        printf("接口名称: %s\n", it->ifr_name);
        printf("IP 地址:  %s\n", ip_addr);
        printf("MAC 地址: %s\n", mac_addr);
        printf("--------------------------------\n");
    }

    close(sockfd);
    return EXIT_SUCCESS;
}

